package com.gitee.qdbp.base.system.service;

import java.util.ArrayList;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import com.gitee.qdbp.base.system.model.IAccountType;
import com.gitee.qdbp.tools.utils.StringTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 用户类型转换
 *
 * @author zhaohuihua
 * @version 180418
 */
public class UserTypeConverter<E extends Enum<E>> implements IUserTypeConverter, Converter<String, IAccountType> {

    private List<IAccountType> types;

    private IAccountType defaults;

    private List<IAccountType> choose;
    
    private Class<E> clazz;

    public UserTypeConverter(Class<E> type, String defaults) {
        this(type, defaults, null);
    }

    public UserTypeConverter(Class<E> type, String defaults, String choose) {
        VerifyTools.requireNotBlank(type, "type");
        VerifyTools.requireNotBlank(type, "defaults");
        
        this.clazz = type;

        if (!IAccountType.class.isAssignableFrom(type)) {
            throw new IllegalArgumentException(type.getSimpleName() + " not instance of IAccountType.");
        }

        E[] enums = type.getEnumConstants();
        if (enums == null) {
            throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
        }
        this.types = new ArrayList<>();
        for (E e : enums) {
            types.add((IAccountType) e);
        }

        this.defaults = convert(defaults);
        if (this.defaults == null) {
            String msg = "default value [" + defaults + "] has not in " + type.getSimpleName() + ".values()";
            throw new IllegalArgumentException(msg);
        }

        this.choose = new ArrayList<>();
        if (VerifyTools.isNotBlank(choose)) {
            String[] array = StringTools.split(choose);
            for (int i = 0; i < array.length; i++) {
                String string = array[i];
                IAccountType temp = convert(string, null);
                if (temp == null) {
                    String msg = "choose value [" + string + "] has not in " + type.getSimpleName() + ".values()";
                    throw new IllegalArgumentException(msg);
                }
                this.choose.add(temp);
            }
        }
    }

    @Override
    public IAccountType convert(String type) {
        return convert(type, defaults);
    }

    private IAccountType convert(String type, IAccountType defaults) {
        if (VerifyTools.isNotBlank(type)) {
            for (IAccountType i : types) {
                if (i.name().equals(type) || String.valueOf(i.ordinal()).equals(type)) {
                    return i;
                }
            }

        }
        return defaults;
    }

    public IAccountType getDefaults() {
        return defaults;
    }

    public List<IAccountType> getChoose() {
        return choose;
    }
    
    public Class<E> getEnumType() {
        return clazz;
    }
}
